package co.edu.unal.geditor.view.tools;

import java.util.HashMap;
import java.util.Map;

public abstract class ToolFactory
{
	protected abstract Tool create();

	// Factories can register as available here
	public static void register( final String className, final ToolFactory factory )
	{
		assert className != null;
		assert factory != null;

		m_factories.put( className, factory );
	}

	public static Tool getDefaultTool()
	{
		return getInstance( LineCreationTool.class.getName() );
	}

	// new in v0.8
	public static Map<String, Tool> getToolSet()
	{
		for ( String className : m_factories.keySet() )
		{
			// fill m_singletons
			getInstance( className );
		}
		
		return m_singletons;
	}
	// new in v0.8

	public static final Tool getInstance( String className )
	{
		assert className != null;

		// Singleton pattern enforced at factory level
		Tool tool = m_singletons.get( className );
		if ( tool == null )
		{
			// first check to see if the Tool (class) factory already exists
			if ( m_factories.containsKey( className ) )
			{
				// ok
			}
			else
			{
				// it doesn't, load it dynamically (good Java feature)
				// no switch is good
				try
				{
					Class.forName( className );

					// when the class object is loaded in the VM
					// *all* static code in the class is executed:
					// see Tool hierarchy
				}
				catch ( ClassNotFoundException exc )
				{
					System.err.println( "Factory not registered." );
				}
			}

			// sanity check
			if ( m_factories.containsKey( className ) )
			{
				// get the factory
				ToolFactory factory = m_factories.get( className );

				// ask the factory for the Tool object
				tool = factory.create();

				// save it
				m_singletons.put( className, tool );
			}
		}

		return tool;
	}

	private static Map<String, ToolFactory> m_factories = new HashMap<String, ToolFactory>();
	private static Map<String, Tool> m_singletons = new HashMap<String, Tool>();
}
